package com.xunshibao.web.security;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;

/**
 * 拦截ServletHandlerMethodResolver的invokeHandlerMethod方法以添加在方法上使用
 * 
 * @Security 注解的功能，参考AnnotationMethodHandlerAdapter的invokeHandlerMethod方法
 */
@Aspect
public class SecurityAspect {
    public SecurityAspect() {
        System.out.println("init");
    }

    // @Before("execution(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.ServletHandlerMethodInvoker.invokeHandlerMethod() && args(handlerMethod, handler, webRequest, implicitModel))")
    @Before("execution(* org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(..)) && args(handlerMethod)")
    public void validateSecurity(Method handlerMethod) {
        // Security sec = handlerMethod.getAnnotation(Security.class);
        // if(sec != null) {
        // System.out.println(handlerMethod.getName());
        // }
        System.out.println(handlerMethod.getName());
    }

    @Around("execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))")
    public Object logTest(ProceedingJoinPoint pjp) throws Throwable {
        AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) pjp.getTarget();
        Class clz = adapter.getClass();
        Method[] mds = clz.getDeclaredMethods();
//        Method m = clz.getMethod("getMethodResolver", Object.class);
        Method m = null;
        if(mds != null) {
            for(Method md : mds) {
                if("getMethodResolver".equals(md.getName())) {
                    m = md;
                    break;
                }
            }
        }
        ReflectionUtils.makeAccessible(m);
        Object[] args = pjp.getArgs();
        Object obj = m.invoke(adapter, args[2]);
        System.out.println("executing aop testing...Book Name : ");
        return pjp.proceed();
    }
}
